import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;

public 
class ChatClient extends Frame implements ActionListener, WindowListener, KeyListener{
	public static ChatClient chatClient = null;
	public List lNicks;
	public TextArea taMain;
	public TextField tfCommand;
	protected Button bConnect;
	protected Button bDisconnect;
	protected Button bExit;
	protected boolean connected;
	protected Socket socket;
	protected ChatClientThread clientThread;
	BufferedReader brSocket;
	DataOutputStream out;

	public ChatClient(){
		super("ChatClient 1.0");
		initLayout();
		addWindowListener(this);
		setVisible(true);
	}
	public void initLayout(){
		setLayout(null);
		setSize(640, 480);

		lNicks = new List();
		lNicks.setBounds(500, 30, 130, 360);
		add(lNicks);

		taMain = new TextArea();
		taMain.setBounds(10, 30, 480, 360);
		add(taMain);

		tfCommand = new TextField();
		tfCommand.setBounds(10, 410, 620, 20);
		tfCommand.addKeyListener(this);
		add(tfCommand);

		bConnect = new Button("Connect");
		bConnect.setBounds(10, 450, 100, 20);
		bConnect.addActionListener(this);
		add(bConnect);

		bDisconnect = new Button("Disconnect");
		bDisconnect.setBounds(120, 450, 100, 20);
		bDisconnect.addActionListener(this);
		add(bDisconnect);

		bExit = new Button("Exit");
		bExit.setBounds(530, 450, 100, 20);
		bExit.addActionListener(this);
		add(bExit);
	}
	public static void main(String args[]){
		chatClient = new ChatClient();
	}
	public void actionPerformed(ActionEvent evt){
		String tmp = evt.getActionCommand();
		if (tmp.equals("Exit")){
			exitClicked();
		}
		else if (tmp.equals("Disconnect")){
			disconnectClicked();
		}
		else if (tmp.equals("Connect")){
			connectClicked();
		}
	}
	public void connect(String host, int port){
		connected = false;
		insertText("Connecting to " + host + "\n");
		try{
			socket = new Socket(host, port);
		}
		catch(IOException e){
			insertText("Socket operation error: " + e + "\n");
			return;
		}
		insertText("Socket initialization completed...\n");
		try{
			out = new DataOutputStream(socket.getOutputStream());
		brSocket = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		}
		catch(IOException e){
			insertText("Error creating i/o streams: " + e + "\n");
			return;
		}
		clientThread = new ChatClientThread(this);
		clientThread.start();
		connected = true;
	}
	public void connectClicked(){
		int port = 6666;
		connect("127.0.0.1", port);
	}
	public void disconnectClicked(){
		if (!connected){
			insertText("Not connected!\n");
			return;
		}
		connected = false;
		clientThread.stopped = true;
		try{
			socket.close();
		}
		catch(IOException e){
			//insertText("Socket operation error: " + e + "\n");
			return;
		}
	}
	public void clientThreadStopped(){
		insertText("Disconnected!\n");
		connected = false;
		try{
			socket.close();
		}
		catch(IOException e){
			//insertText("Socket operation error: " + e + "\n");
			return;
		}
	}
	public void keyPressed(int keyCode){
		if (keyCode != KeyEvent.VK_ENTER){
			return;
		}
		if (!connected){
			insertText("Not connected!\n");
			return;
		}
		String line = tfCommand.getText();
		if (line.equals("")) return;
		tfCommand.setText("");
		try{
			out.writeBytes(line + "\n");
			out.flush();
		}
		catch(IOException e){
			insertText("Socket operation error: " + e + "\n");
		}
	}
	public void insertText(String line){
		synchronized(taMain){
			taMain.insert(line, 0);
		}
	}
	public void exitClicked(){
		System.exit(0);
	}
	public void windowDeiconified(WindowEvent evt){
	}
	public void windowClosed(WindowEvent evt){
	}
	public void windowDeactivated(WindowEvent evt){
	}
	public void windowClosing(WindowEvent evt){
		exitClicked();
	}
	public void windowActivated(WindowEvent evt){
	}
	public void windowIconified(WindowEvent evt){
	}
	public void windowOpened(WindowEvent evt){
	}
	public void keyPressed(KeyEvent evt){
		keyPressed(evt.getKeyCode());
	}
	public void keyReleased(KeyEvent evt){
	}
	public void keyTyped(KeyEvent evt){
	}
}
